package automaton;

import java.util.Vector;

public class Manager {
	
	private Vector<AbstractConfiguration> configs;
	private Semaphore semaphoreForAut;
	private Semaphore managerMutex;
	private Result resultObj;
	
	public Manager(){
		this.configs = new Vector<AbstractConfiguration>();
		this.semaphoreForAut = new Semaphore(1);
		this.managerMutex = new Semaphore(1);
		this.semaphoreForAut.down();
	}
	
	public StartConfiguration createStartConfig(Automaton aut, State startState, String input){
		StartConfiguration startConfig = new StartConfiguration(this, aut, startState, input);
		this.managerMutex.down();
		this.configs.add(startConfig);
		this.managerMutex.up();
		startConfig.start();
		return startConfig;
	}
	
	public Configuration newConfig(Automaton aut, State state, String input, String output, AbstractConfiguration preConfig, int lengthOfOutputOnCreate){
		Configuration newConfig = new Configuration(this, aut, state, input, output, preConfig, lengthOfOutputOnCreate);
		this.managerMutex.down();
		this.configs.add(newConfig);
		this.managerMutex.up();
		newConfig.start();
		return newConfig;
	}
	
	public void calculateResult(AbstractConfiguration config){
		this.managerMutex.down();
		String resultStr = config.getCompleteOutputString();
		this.resultObj = new SuccessResult(resultStr);
		this.stopAllConfigs(config);
		this.semaphoreForAut.up();
		this.managerMutex.up();
	}
	
	private void stopAllConfigs(AbstractConfiguration config) {
		for(AbstractConfiguration current : this.configs){
			current.stop();
		}
	}

	public void fail(AbstractConfiguration config){
		this.managerMutex.down();
		config.stop();
		this.configs.remove(config);
		if(this.configs.size() == 0) {
			this.resultObj = new FailResult();
			this.semaphoreForAut.up();
		}
		this.managerMutex.up();
		
	}
	
	public void waitTillFirstIsReady(){
		this.semaphoreForAut.down();
	}

	public Result getResult() {
		return resultObj;
	}
	
	
	
}
